/*
 * Corey McGee
 * Data Analysis
 * CS 480/481
 */
package userInterface;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import configuration.UserFields_XmlReader;
import configuration.UserFields_XmlWriter;

import main.Task;
import fields.FieldMatcher;
import fileProcessing.ParsingException;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

public class MainPage extends JFrame implements ActionListener, PropertyChangeListener {
	
	//Global variables
	JTextArea status = new JTextArea("Ready to begin.\n");
	JTextField newField = new JTextField();
	JList fieldList;
	DefaultListModel listOfFields;
	public JProgressBar progressBar = new JProgressBar(0, 100);
	public JButton parseFile = new JButton("Read/Parse a File");
	JCheckBox db = new JCheckBox("Send to Database");
	Boolean sendDB = false;
	JButton exit = new JButton("Exit");
	JButton add = new JButton("Add");
	JButton remove = new JButton("Remove");
	final JFileChooser fc = new JFileChooser();
	public Task task;
	public static FieldMatcher fieldMatcher;
	
	/**
	 * MainPage constructor
	 */
	public MainPage() {

		//Instantiate the fields to use when parsing
		fieldMatcher = FieldMatcher.getInstance();
		try {
			new UserFields_XmlReader();
		} catch (ParsingException e) {
			e.printStackTrace();
		}
		listOfFields = getListOfFields(); //instantiate the list of fields
		
		JTabbedPane tab = new JTabbedPane(); //tabbed panel
		JPanel main = new JPanel(new GridLayout(1, 2, 50, 0)); //main panel (tab 1) to hold parsing stuff
		JPanel options = new JPanel(new GridLayout(2, 1, 0, 10)); //right panel to hold parsing buttons
		JPanel dbExit = new JPanel(new GridLayout(1, 2)); //bottom right panel to hold check box and exit button
		JPanel side = new JPanel(new BorderLayout()); //left panel to hold progress bar and status box
		JPanel fields = new JPanel(new GridLayout(1, 2, 50, 0)); //fields panel (tab 2) for use in adding/removing custom fields
		JPanel fieldOptions = new JPanel(new GridLayout(3, 1, 0, 10)); //right panel to hold field option buttons
		
		Border title = new TitledBorder("Please select an option");
		JScrollPane scroll = new JScrollPane(status); //scroll pane for status box
		fieldList = new JList(listOfFields); //list of custom fields
		fieldList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //only allow one field selected at a time
		fieldList.setLayoutOrientation(JList.VERTICAL);
		fieldList.setVisibleRowCount(-1);
		JScrollPane fieldScroll = new JScrollPane(fieldList); //scroll pane for custom fields list
		
		status.setMargin(new Insets(5, 5, 5, 5));
		status.setEditable(false);
		progressBar.setValue(0); //initialize progress bar to 0
		progressBar.setStringPainted(true);
		db.setSelected(false); //by default, we send to the database
		
		//add event listeners to buttons and check box
		db.addActionListener(this);
		parseFile.addActionListener(this);
		exit.addActionListener(this);
		add.addActionListener(this);
		remove.addActionListener(this);
		
		//add components to panels
		/*
		 * General Idea
		 * _________________________________________      ______________________________
		 * | ______________        Select Option   |     | ___________   _____________  |
		 * ||______0_______|         _________     |     ||field1     | |             | |
		 * || Status       |        |  Parse  |    |     ||field2     |  -------------  |
		 * ||              |         ---------     |     ||field3     |  _____________  |
		 * ||              |         _  __________ |     ||...        | |    Add      | |
		 * ||              |        |d||  Exit    ||     ||           |  -------------  |
		 * | --------------          -  ---------  |     ||           |  _____________  |
		 *  ---------------------------------------      ||           | |   Remove    | |
		 *                                               | -----------   -------------  |
		 *                                                ------------------------------
		 */
		
		//Main Page (parsing)
		options.add(parseFile);
		dbExit.add(db);
		dbExit.add(exit);
		options.add(dbExit);
		options.setBorder(title);
		side.add(progressBar, BorderLayout.NORTH);
		side.add(scroll, BorderLayout.CENTER);
		main.add(side);
		main.add(options);
		main.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
		
		//Field Page
		fieldOptions.add(newField);
		fieldOptions.add(add);
		fieldOptions.add(remove);
		fields.add(fieldScroll);
		fields.add(fieldOptions);
		fields.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
		
		//add to tabbed panel
		tab.addTab("Parsing", null, main, "Main Page");
		tab.addTab("Fields", null, fields, "Displays fields");
		
		getRootPane().setDefaultButton(parseFile); //set default button
		getContentPane().add(tab);
	}
	/**
	 * Retrieves the current fields to be examined while parsing
	 * Returns a list of the fields to be used in the fields panel
	 * @return
	 */
	private DefaultListModel getListOfFields() {
		DefaultListModel list = new DefaultListModel();
		ArrayList<String> fields = fieldMatcher.getCustomHeaderLineCheck();
		for(String field : fields) {
			list.addElement(field);
		}
		return list;
	}
	/**
	 * Updates the status box with the current status of the program
	 * @param newStatus
	 */
	public void setStatus(String newStatus) {
		status.append(newStatus);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == exit) { //Exit button
			status.append("Exiting...");
			new UserFields_XmlWriter("userfields"); //write user fields to XML file
			new UserFields_XmlWriter("searchwords"); //write search words to XML file
			fc.cancelSelection(); //clears anything on the FileChooser
			fieldList.clearSelection(); //clears anything on the field list
			System.exit(0); //terminate program
		}
		else if(e.getSource() == parseFile) { //Parse button
			//Display all possible files to be parsed
			//Currently displays all files.  Can be configure for what we need
			fc.removeChoosableFileFilter(new ParsedFileFilter());
			fc.setAcceptAllFileFilterUsed(true);
			
			int returnVal = fc.showDialog(this, "Parse"); //display FileChooser, with modified 'parse' button
			if(returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fc.getSelectedFile();
				status.setText(""); //reset status
				parseFile.setEnabled(false); //only allow one file to be parsed at a time
				progressBar.setValue(0); //reset progress bar
				setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); //put cursor on busy signal
				
				//thread the parsing to a Task
				task = new Task(file, sendDB);
				task.addPropertyChangeListener(this);
				task.execute();
			}
		}
		else if(e.getSource() == db) { //Send to Database check box
			if(db.isSelected()) {
				sendDB = true; //user wants to send to the database
			}
			else {
				sendDB = false; //user does not want to send to the database
			}
		}
		else if(e.getSource() == add) { //Add new field button
			String fieldName = newField.getText(); //pull what user typed
			if(fieldName != null) {
				if(!fieldMatcher.getCustomHeaderLineCheck().contains(fieldName)) { //check if such a field already exists
					fieldMatcher.addNewSearchWord(fieldName);
					new UserFields_XmlWriter("userfields");
					new UserFields_XmlWriter("searchwords"); //write new search word to XML file
					listOfFields.addElement(fieldName); //update list with new field
				}
			}
		}
		else if(e.getSource() == remove) { //Remove field button
			int index = fieldList.getSelectedIndex(); //get selected option (if applicable)
			String fieldName = newField.getText(); //get input text (if applicable)
			if(index >= 0) { //if selection in list
				fieldMatcher.removeSearchWord(index);
				new UserFields_XmlWriter("userfields");
				new UserFields_XmlWriter("searchwords"); //update XML file
				listOfFields.remove(index); //update list
			}
			else if(fieldName != null) { //no selection, check what user typed in
				if(fieldMatcher.getCustomHeaderLineCheck().contains(fieldName)) { //check if user input matches a field 
					index = fieldMatcher.getCustomHeaderLineCheck().indexOf(fieldName);
					fieldMatcher.removeSearchWord(index);
					new UserFields_XmlWriter("userfields");
					new UserFields_XmlWriter("searchwords"); //update XML file
					listOfFields.remove(index); //update list
				}
			}
		}
		else { //fail-safe
			System.out.println("There was an error.  Ending Program.");
			System.exit(0); //terminate program
		}
		
	}
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if("progress" == evt.getPropertyName()) {
			int prog = (Integer) evt.getNewValue();
			progressBar.setValue(prog); //update progress bar
		}
	}
}
